#include <Arduino.h>

#ifndef LIGHT_CAR
#define LIGHT_CAR

/**
 * @brief
 * esp32 analogWrite 里设置的 duty_resolution 默认是8 则最大值 255。
 * 而8266默认pwm范围是1023
 * esp8266可以使用analogWriteRange 设置范围
 *
 */


#ifdef ESP8266
const int MAX_SPEED = 1023;
#elif defined ESP32
const int MAX_SPEED = 255;
#endif

const int ZERO_SPEED = 0;

/**
 * 马达状态，正转反转和停止
 * */
enum MotorState { Positive, Reverse, Stop };

class BiDirectionalMotor {
    // 正转
    uint8_t posPin;
    // 反转
    uint8_t resPin;
    MotorState motorState = Stop;
    MotorState lastState = Stop;

   public:
    BiDirectionalMotor(uint8_t posPin, uint8_t resPin)
        : posPin(posPin), resPin(resPin) {}
    void begin();

    /**
     * 切换马达状态到指定状态。
     * */
    void turn(MotorState state);

    void changeSpeed(int changeTo);

    //解除转弯状态，返回直线的时候，就需要与上次状态一致了
    void afterTurn();
};

/**
 * @brief 小车，使用左右马达操作，{@link BiDirectionalMotor @endlink}
 *  左右的两组 pwm引脚可以各自分线，各自控制  两组pwm针脚
 *
 *
 */
class Car {
   private:
    BiDirectionalMotor leftMotor;

    BiDirectionalMotor rightMotor;

    bool isForward = true;

   public:
    Car(const BiDirectionalMotor& leftMotor, const BiDirectionalMotor& rightMotor)
        : leftMotor(leftMotor), rightMotor(rightMotor) {}
    void begin();
    void forward();

    void backward();

    void turnRight();

    void endTurnRight();

    void turnLeft();

    void endTurnLeft();

    void stop();

    void goPikachu();

    void setSpeed(int percentage);

    /**
     * @brief 小车操作表，通过索引获取函数来回调
     *
     */
    void (Car::*generalFunTab[8])() = {
        &Car::forward,     &Car::backward,     &Car::turnLeft, &Car::turnRight,
        &Car::endTurnLeft, &Car::endTurnRight, &Car::stop,     &Car::goPikachu};

    void (Car::*speedFunTab[1])(int) = {&Car::setSpeed};
};

#endif